﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="DateTimeWrapper.cs" company="Vlady-mix">
//   Vlady-mix 2015
// </copyright>
// <summary>
//   Implements a wrapper for DateTime that provides formatted strings for DatePicker.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace CustomDatePicker.Controls.DatePicker
{
    using System;
    using System.ComponentModel;
    using System.Globalization;

    /// <summary>
    ///     Implements a wrapper for DateTime that provides formatted strings for DatePicker.
    /// </summary>
    public sealed class DateTimeWrapper : INotifyPropertyChanged
    {
        #region Private Fields

        /// <summary>
        ///     The date time.
        /// </summary>
        private DateTime dateTime;

        #endregion

        #region Constructor
        /// <summary>
        /// Initializes a new instance of the DateTimeWrapper class.
        /// </summary>
        /// <param name="dateTime">
        /// DateTime to wrap.
        /// </param>
        public DateTimeWrapper(DateTime dateTime)
        {
            this.DateTime = dateTime;
        }
        #endregion

        #region Interface Members

        /// <summary>
        ///     The property changed.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region Public Static Methods

        /// <summary>
        ///     Returns a value indicating whether the current culture uses a 24-hour clock.
        /// </summary>
        /// <returns>True if it uses a 24-hour clock; false otherwise.</returns>
        public static bool CurrentCultureUsesTwentyFourHourClock()
        {
            return !CultureInfo.CurrentCulture.DateTimeFormat.LongTimePattern.Contains("t");
        }

        #endregion

        #region Public Properties

        /// <summary>
        ///     Gets or sets the DateTime being wrapped.
        /// </summary>
        public DateTime DateTime
        {
            get
            {
                return this.dateTime;
            }

            set
            {
                if (this.dateTime == value)
                {
                    return;
                }

                this.dateTime = value;

                if (this.PropertyChanged == null)
                {
                    return;
                }

                // Raise Date changed
                this.PropertyChanged(this, new PropertyChangedEventArgs("DateTime"));

                // Raise on Day Name because it's not the same day on differents month / years
                var onPropertyChanged = this.PropertyChanged;
                if (onPropertyChanged != null)
                {
                    onPropertyChanged(this, new PropertyChangedEventArgs("DayName"));

                    // Raise on Day Name because it's not the same day on differents month / years
                    onPropertyChanged(this, new PropertyChangedEventArgs("DayNumber"));
                }
            }
        }

        /// <summary>
        ///     Gets the 4-digit year as a string.
        /// </summary>
        public string YearNumber
        {
            get
            {
                return this.DateTime.ToString("yyyy", CultureInfo.CurrentCulture);
            }
        }

        /// <summary>
        ///     Gets the 2-digit month as a string.
        /// </summary>
        public string MonthNumber
        {
            get
            {
                return this.DateTime.ToString("MM", CultureInfo.CurrentCulture);
            }
        }

        /// <summary>
        ///     Gets the month name as a string.
        /// </summary>
        public string MonthName
        {
            get
            {
                return this.DateTime.ToString("MMMM", CultureInfo.CurrentCulture);
            }
        }

        /// <summary>
        ///     Gets the 2-digit day as a string.
        /// </summary>
        public string DayNumber
        {
            get
            {
                return this.DateTime.ToString("dd", CultureInfo.CurrentCulture);
            }
        }

        /// <summary>
        ///     Gets the day name as a string.
        /// </summary>
        public string DayName
        {
            get
            {
                return this.DateTime.ToString("dddd", CultureInfo.CurrentCulture);
            }
        }

        /// <summary>
        ///     Gets the hour as a string.
        /// </summary>
        public string HourNumber
        {
            get
            {
                return this.DateTime.ToString(
                    CurrentCultureUsesTwentyFourHourClock() ? "%H" : "%h",
                    CultureInfo.CurrentCulture);
            }
        }

        /// <summary>
        ///     Gets the 2-digit minute as a string.
        /// </summary>
        public string MinuteNumber
        {
            get
            {
                return this.DateTime.ToString("mm", CultureInfo.CurrentCulture);
            }
        }

        /// <summary>
        ///     Gets the 2-digit seconds as a string.
        /// </summary>
        public string SecondNumber
        {
            get
            {
                return this.DateTime.ToString("%s", CultureInfo.CurrentCulture);
            }
        }

        /// <summary>
        ///     Gets the AM/PM designator as a string.
        /// </summary>
        public string AmPmString
        {
            get
            {
                return this.DateTime.ToString("tt", CultureInfo.CurrentCulture);
            }
        }

        #endregion
    }

    #region Nested type: DateTimeWrapperExtensions

    /// <summary>
    ///     The date time wrapper extensions.
    /// </summary>
    internal static class DateTimeWrapperExtensions
    {
        #region Public Static Methods

        /// <summary>
        /// The to date time wrapper.
        /// </summary>
        /// <param name="dateTime">
        /// The date time.
        /// </param>
        /// <returns>
        /// The <see cref="DateTimeWrapper"/>.
        /// </returns>
        public static DateTimeWrapper ToDateTimeWrapper(this DateTime dateTime)
        {
            return new DateTimeWrapper(dateTime);
        }

        #endregion
    }

    #endregion
}